/* ************************************************************************
 *       Filename:  link.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2018年09月29日 11时22分09秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (), 
 *        Company:  
 * ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "link.h"

/*************************************************************************
* Function:     void create_link(s_msg_t **head, s_msg_t *p_new)
* Description:  创建/追加链表
* Input:        
*               s_msg_t **head 链表头部
*               s_msg_t *p_new 链表新节点
* Return:       NULL
* Others:       NULL
**************************************************************************/
void create_link(s_msg_t **head, s_msg_t *p_new)
{
	if(NULL == (*head))
	{
		LOGD("The current link is NULL, p_new is link head.");
		(*head) = p_new;
		(*head)->next = NULL;
	}
	else
	{
		LOGD("The current link has data, add nodes to last one.");
		s_msg_t *p_tmp = (*head);
		while(NULL != p_tmp->next)
		{
			p_tmp = p_tmp->next;
		}

		p_tmp->next = p_new;
		p_new->next = NULL;
	}
}

/*************************************************************************
* Function:     void free_link(s_msg_t **head)
* Description:  释放链表
* Input:        
*               s_msg_t **head 链表头部
* Return:       NULL
* Others:       NULL
**************************************************************************/
void free_link(s_msg_t **head)
{
	if(NULL == (*head))
	{
		LOGD("The current link is NULL, return.");
		return ;
	}
	LOGD("Free link...");
	s_msg_t *p_tmp = NULL;
	while(NULL != (*head))
	{
		p_tmp = (*head);
		(*head) = p_tmp->next;
		free(p_tmp);
	}
}

/*************************************************************************
* Function:     void show_link_nodes(s_msg_t *head)
* Description:  打印链表节点
* Input:        
*               s_msg_t **head 链表头部
* Return:       NULL
* Others:       NULL
**************************************************************************/
void show_link_nodes(s_msg_t *head)
{
	if(NULL == head)
	{
		LOGD("The current link is NULL, return.");
		return ;		
	}

	s_msg_t *p_tmp = head;
	while(NULL != p_tmp)
	{
		LOGD("count: %d, str: %s", p_tmp->count, p_tmp->str);
		p_tmp = p_tmp->next;
	}
}

/*************************************************************************
* Function:     s_msg_t *serach_node_for_link_as_count(s_msg_t *head,
*                                                               int count)
* Description:  按Count查找节点，并打印
* Input:        
*               s_msg_t **head 链表头部
*               int count      查找的内容
* Return:       NULL
* Others:       NULL
**************************************************************************/
s_msg_t *serach_node_for_link_as_count(s_msg_t *head, int count)
{
	if(NULL == head)
	{
		LOGD("The current link is NULL, return.");
		return NULL;		
	}
	else
	{
		s_msg_t *p_tmp = head;
		while(NULL != p_tmp)
		{
			if(count == p_tmp->count)
			{
				LOGD("Find node: Count: %d, Buffer: %s", p_tmp->count, p_tmp->str);
			}
			p_tmp = p_tmp->next;
		}
	}
	return NULL;
}

/*************************************************************************
* Function:     s_msg_t *serach_node_for_link_as_count(s_msg_t *head,
*                                                            char *buffer)
* Description:  按Buffer查找节点，并打印
* Input:        
*               s_msg_t **head 链表头部
*               char *buffer   查找的内容
* Return:       NULL
* Others:       NULL
**************************************************************************/
s_msg_t *serach_node_for_link_as_buffer(s_msg_t *head, char *buffer)
{
	if(NULL == head)
	{
		LOGD("The current link is NULL, return.");
		return NULL;		
	}
	else
	{
		s_msg_t *p_tmp = head;
		while(NULL != p_tmp)
		{
			if(0 == strncmp(p_tmp->str, buffer, strlen(buffer)))
			{
				LOGD("Find node: Count: %d, Buffer: %s", p_tmp->count, p_tmp->str);
			}
			p_tmp = p_tmp->next;
		}
	}
	return NULL;
}

/*************************************************************************
* Function:     delete_nodes_for_link_as_count(s_msg_t **head, int count)
* Description:  按Count删除节点
* Input:        
*               s_msg_t **head 链表头部
*               int count      需要删除节点的数据
* Return:       NULL
* Others:       NULL
**************************************************************************/
void delete_nodes_for_link_as_count(s_msg_t **head, int count)
{
	if(NULL == (*head))
	{
		LOGD("The current link is NULL, return.");
		return ;		
	}
	else
	{
		s_msg_t *p_f = NULL;
		s_msg_t *p_n = NULL;
		p_f = p_n = (*head);

		while((count != p_n->count) && (NULL != p_n->next))
		{
			p_f = p_n;
			p_n = p_n->next;
		}

		if(count == p_n->count)
		{
			if(p_n == (*head))
			{
				LOGD("Delete head, the head->next is new head.");
				(*head) = p_n->next;
			}
			else
			{
				LOGD("Delete link body.");
				p_f->next = p_n->next;
			}
			free(p_n);
		}
		else
		{
			LOGD("Not find the Count is %d nodes.", count);
		}
	}
}

/*************************************************************************
* Function:     delete_nodes_for_link_as_count(s_msg_t **head, char *buffer)
* Description:  按Buffer删除节点
* Input:        
*               s_msg_t **head 链表头部
*               char *buffer   需要删除节点的数据
* Return:       NULL
* Others:       NULL
**************************************************************************/
void delete_nodes_for_link_as_buffer(s_msg_t **head, char *buffer)
{
	if(NULL == (*head))
	{
		LOGD("The current link is NULL, return.");
		return ;		
	}
	else
	{
		s_msg_t *p_f = NULL;
		s_msg_t *p_n = NULL;
		p_f = p_n = (*head);

		while((0 != strcmp(p_n->str, buffer)) && (NULL != p_n->next))
		{
			p_f = p_n;
			p_n = p_n->next;
		}

		if(0 == strcmp(p_n->str, buffer))
		{
			if(p_n == (*head))
			{
				LOGD("Delete head, the head->next is new head.");
				(*head) = p_n->next;
			}
			else
			{
				LOGD("Delete link body.");
				p_f->next = p_n->next;
			}
			free(p_n);
		}
		else
		{
			LOGD("Not find the Buffer is %s nodes.", buffer);
		}
	}
}

/*************************************************************************
* Function:     insert_nodes_for_link_as_count(s_msg_t **head, s_msg_t *p_new)
* Description:  插入链表
* Input:        
*               s_msg_t **head 链表头部
*               s_msg_t *p_new 链表新节点
* Return:       NULL
* Others:       NULL
**************************************************************************/
void insert_nodes_for_link_as_count(s_msg_t **head, s_msg_t *p_new)
{
	if(NULL == (*head))
	{
		LOGD("The current link is NULL, new node is link head.");
		(*head) = p_new;
		p_new->next = NULL;
	}
	else
	{
		s_msg_t *p_f = NULL;
		s_msg_t *p_n = NULL;
		p_f = p_n = (*head);

		while((p_new->count >= p_n->count) && (NULL != p_n->next))
		{
			p_f = p_n;
			p_n = p_n->next;
		}

		if(p_new->count < p_n->count)
		{
			if(p_n == (*head))
			{
				LOGD("Insert beyound head.");
				p_new->next = (*head);
				*(head) = p_new;
			}
			else
			{
				LOGD("Insert body.");
				p_f->next = p_new;
				p_new->next = p_n;
			}
		}
		else
		{
			LOGD("Insert last one.");
			p_n->next = p_new;
			p_new->next = NULL;
		}
	}
}

/*************************************************************************
* Function:     void order_link(s_msg_t **head)
* Description:  打印链表节点
* Input:        
*               s_msg_t **head 链表头部
* Return:       NULL
* Others:       NULL
**************************************************************************/
void order_link(s_msg_t **head)
{
	if(NULL == (*head))
	{
		LOGD("The node is NULL, return.");
		return ;	
	}
	if(NULL == (*head)->next)
	{
		LOGD("The node is only one, return.");
		return ;
	}

	s_msg_t *p_f   = NULL;
	s_msg_t *p_n   = NULL;
	s_msg_t p_tmp;
	p_f = p_n = *head;
	while(NULL != p_f->next)
	{
		p_n = p_f->next;
		while(NULL != p_n)
		{
			if(p_f->count > p_n->count)
			{
				p_tmp = *p_f;
				*p_f  = *p_n;
				*p_n  = p_tmp;

				p_tmp.next = p_f->next;
				p_f->next  = p_n->next;
				p_n->next  = p_tmp.next;
			}
			p_n = p_n->next;
		}
		p_f = p_f->next;
	}
}

// 链表反转
void reverse_link(s_msg_t **head)
{
	if(NULL == (*head))
	{
		LOGD("The node is NULL, return.");
		return ;		
	}
	if(NULL == (*head)->next)
	{
		LOGD("The node is only one, return.");
		return ;	
	}
	
	s_msg_t *p_f = NULL;
	s_msg_t *p_n = NULL;
	s_msg_t *p_r = NULL;
	p_f = *head;
	p_n = p_f->next;
	while(NULL != p_n)
	{
		p_r = p_n->next;
		p_n->next = p_f;
		p_f = p_n;
		p_n = p_r;
	}
	(*head)->next = NULL;
	*head = p_f;
}